//
// Created by root on 19-8-1.
//

#include "hook_audio_record.h"
#include <string>
#include <unistd.h>
#include "AndHook.h"
#include "log_utils.h"
#include "inject_compacter.h"
#include "method_utils.h"

#define TAG "AudioRecord"

static jmethodID old_method= nullptr;

#define OPERATION_NAME "audioRecord"

//private native final int native_setup(Object audiorecord_this,
//            Object /*AudioAttributes*/ attributes,
//            int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
//            int buffSizeInBytes, int[] sessionId, String opPackageName,
//            long nativeRecordInJavaObj);
int my_native_setup(JNIEnv *env,jobject instance,
                    jobject audiorecord_this,
           jobject /*AudioAttributes*/ attributes,
           jintArray sampleRate, int channelMask, int channelIndexMask, int audioFormat,
           int buffSizeInBytes, jintArray sessionId, jstring opPackageName,
           long nativeRecordInJavaObj){
    if(!old_method){
        LOGE("old_method is nullptr\n");
        return JNI_ERR;
    }
    std::string operation=std::string(OPERATION_NAME);
    if(!post_auth_request(env,operation)){
        LOGE("user denies to let process:%d use microphone\n", getpid());
        return JNI_ERR;
    }
    LOGD("user allows to let process:%d use microphone\n", getpid());

    int init_ret=env->CallIntMethod(instance,old_method,
                                    audiorecord_this,
                                    attributes,
                                    sampleRate,channelMask,channelIndexMask,audioFormat,
                                    buffSizeInBytes,sessionId,opPackageName,
                                    nativeRecordInJavaObj);
    return init_ret;
}

void hook_audio_record_setup(JNIEnv *env) {
    jclass audio_record_class=env->FindClass("android/media/AudioRecord");
    //private native final int native_setup(Object audiorecord_this,
//            Object /*AudioAttributes*/ attributes,
//            int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
//            int buffSizeInBytes, int[] sessionId, String opPackageName,
//            long nativeRecordInJavaObj);
    jmethodID native_setup=get_method_by_name(env,audio_record_class,"native_setup");
    if(!native_setup)
        return;
    AKJavaHookMethodV(env,native_setup,
            reinterpret_cast<void*>(my_native_setup),&old_method);
    LOGD("old_method:%p\n",old_method);
}
